package cn.edu.ncut.cs.springboot.petmanagementsystem.service.Impl;

import cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.ServiceReservationMapper;
import cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.ServiceTypeMapper;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.ServiceReservation;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.ServiceType;
import cn.edu.ncut.cs.springboot.petmanagementsystem.service.PetServiceService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@Service
public class PetServiceServiceImpl implements PetServiceService {

    @Autowired
    private ServiceTypeMapper serviceTypeMapper;

    @Autowired
    private ServiceReservationMapper reservationMapper;

    @Override
    public List<ServiceType> getServiceTypeList() {
        LambdaQueryWrapper<ServiceType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ServiceType::getStatus, 1); // 只查询启用状态
        wrapper.orderByAsc(ServiceType::getId);
        return serviceTypeMapper.selectList(wrapper);
    }

    @Override
    public ServiceType getServiceTypeById(Long id) {
        if (id == null) {
            return null;
        }
        return serviceTypeMapper.selectById(id);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public boolean reserveService(ServiceReservation reservation) {
        if (reservation == null || reservation.getUserId() == null || 
            reservation.getServiceTypeId() == null || reservation.getPetId() == null) {
            throw new IllegalArgumentException("参数不完整");
        }

        // 查询服务类型，获取价格
        ServiceType serviceType = serviceTypeMapper.selectById(reservation.getServiceTypeId());
        if (serviceType == null) {
            throw new IllegalArgumentException("服务类型不存在");
        }
        if (serviceType.getStatus() != 1) {
            throw new IllegalArgumentException("该服务已停用");
        }

        // 如果前端没有传 totalAmount，则使用服务类型的价格
        if (reservation.getTotalAmount() == null) {
            reservation.setTotalAmount(serviceType.getPrice());
        }

        // 生成预约单号
        reservation.setReservationNo("SRV" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase());
        reservation.setReservationStatus(1); // 待确认
        reservation.setCreateTime(LocalDateTime.now());
        reservation.setUpdateTime(LocalDateTime.now());

        int result = reservationMapper.insert(reservation);
        return result > 0;
    }

    @Override
    public IPage<ServiceReservation> getReservationList(Long userId, Long petId, Integer pageNum, Integer pageSize) {
        Page<ServiceReservation> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<ServiceReservation> wrapper = new LambdaQueryWrapper<>();
        
        if (userId != null) {
            wrapper.eq(ServiceReservation::getUserId, userId);
        }
        if (petId != null) {
            wrapper.eq(ServiceReservation::getPetId, petId);
        }
        
        wrapper.orderByDesc(ServiceReservation::getCreateTime);
        return reservationMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public boolean confirmReservation(Long id) {
        if (id == null) {
            return false;
        }

        ServiceReservation reservation = reservationMapper.selectById(id);
        if (reservation == null) {
            return false;
        }

        reservation.setReservationStatus(2); // 已确认
        reservation.setUpdateTime(LocalDateTime.now());
        int result = reservationMapper.updateById(reservation);
        return result > 0;
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public boolean finishReservation(Long id) {
        if (id == null) {
            return false;
        }

        ServiceReservation reservation = reservationMapper.selectById(id);
        if (reservation == null) {
            return false;
        }

        reservation.setReservationStatus(4); // 已完成
        reservation.setCompletionTime(LocalDateTime.now());
        reservation.setUpdateTime(LocalDateTime.now());
        int result = reservationMapper.updateById(reservation);
        return result > 0;
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public boolean cancelReservation(Long id, Long userId) {
        if (id == null || userId == null) {
            return false;
        }

        ServiceReservation reservation = reservationMapper.selectById(id);
        if (reservation == null || !reservation.getUserId().equals(userId)) {
            return false;
        }

        // 只能取消待确认或已确认的预约
        if (reservation.getReservationStatus() == 1 || reservation.getReservationStatus() == 2) {
            reservation.setReservationStatus(5); // 已取消
            reservation.setUpdateTime(LocalDateTime.now());
            int result = reservationMapper.updateById(reservation);
            return result > 0;
        }

        return false;
    }

    @Override
    public boolean checkAvailability(Long serviceTypeId, LocalDateTime reservationDate) {
        if (serviceTypeId == null || reservationDate == null) {
            return false;
        }

        // 检查服务类型是否存在且启用
        ServiceType serviceType = serviceTypeMapper.selectById(serviceTypeId);
        if (serviceType == null || serviceType.getStatus() != 1) {
            return false;
        }

        // 检查预约时间是否在过去
        if (reservationDate.isBefore(LocalDateTime.now())) {
            return false;
        }

        // 检查该时间段是否已有预约（简化实现：每个时间段只能有一个预约）
        // 实际应用中可以根据服务类型设置并发预约数量
        LambdaQueryWrapper<ServiceReservation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ServiceReservation::getServiceTypeId, serviceTypeId);
        wrapper.eq(ServiceReservation::getReservationDate, reservationDate);
        wrapper.in(ServiceReservation::getReservationStatus, Arrays.asList(1, 2, 3)); // 待确认、已确认、进行中

        Long count = reservationMapper.selectCount(wrapper);
        
        // 假设每个时间段最多3个预约
        return count < 3;
    }

    @Override
    public List<Map<String, Object>> getAvailableTimes(Long serviceTypeId, String date) {
        List<Map<String, Object>> availableTimes = new ArrayList<>();

        if (serviceTypeId == null || date == null) {
            return availableTimes;
        }

        try {
            // 解析日期
            LocalDate targetDate = LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE);
            
            // 检查日期是否在过去
            if (targetDate.isBefore(LocalDate.now())) {
                return availableTimes;
            }

            // 检查服务类型
            ServiceType serviceType = serviceTypeMapper.selectById(serviceTypeId);
            if (serviceType == null || serviceType.getStatus() != 1) {
                return availableTimes;
            }

            // 生成当天的时间段（营业时间：9:00-18:00，每小时一个时间段）
            LocalTime currentTime = LocalTime.now();
            boolean isToday = targetDate.equals(LocalDate.now());

            for (int hour = 9; hour < 18; hour++) {
                LocalTime slotTime = LocalTime.of(hour, 0);
                LocalDateTime slotDateTime = LocalDateTime.of(targetDate, slotTime);

                // 如果是今天，跳过已经过去的时间
                if (isToday && slotTime.isBefore(currentTime)) {
                    continue;
                }

                // 检查该时间段的可用性
                boolean available = checkAvailability(serviceTypeId, slotDateTime);

                // 统计该时间段的预约数量
                LambdaQueryWrapper<ServiceReservation> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(ServiceReservation::getServiceTypeId, serviceTypeId);
                wrapper.eq(ServiceReservation::getReservationDate, slotDateTime);
                wrapper.in(ServiceReservation::getReservationStatus, Arrays.asList(1, 2, 3));
                Long bookedCount = reservationMapper.selectCount(wrapper);

                Map<String, Object> timeSlot = new HashMap<>();
                timeSlot.put("time", slotTime.toString());
                timeSlot.put("dateTime", slotDateTime);
                timeSlot.put("available", available);
                timeSlot.put("bookedCount", bookedCount);
                timeSlot.put("maxCapacity", 3);
                timeSlot.put("remainingSlots", 3 - bookedCount);

                availableTimes.add(timeSlot);
            }

        } catch (Exception e) {
            log.error("获取可预约时间段失败", e);
        }

        return availableTimes;
    }

    @Override
    public IPage<ServiceReservation> getMyHistory(Long userId, Integer pageNum, Integer pageSize) {
        if (userId == null) {
            return new Page<>(pageNum, pageSize);
        }

        Page<ServiceReservation> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<ServiceReservation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ServiceReservation::getUserId, userId);
        wrapper.orderByDesc(ServiceReservation::getCreateTime);

        return reservationMapper.selectPage(page, wrapper);
    }

    @Override
    public Map<String, Object> calculateFosterCost(LocalDateTime startDate, LocalDateTime endDate, Long petId) {
        Map<String, Object> result = new HashMap<>();
        
        if (startDate == null || endDate == null) {
            result.put("error", "日期参数不能为空");
            return result;
        }
        
        if (startDate.isAfter(endDate)) {
            result.put("error", "开始日期不能晚于结束日期");
            return result;
        }
        
        // 计算寄养天数（向上取整）
        long days = java.time.temporal.ChronoUnit.DAYS.between(startDate.toLocalDate(), endDate.toLocalDate());
        if (days == 0) {
            days = 1; // 至少算一天
        }
        
        // 基础价格（每天）
        double basePrice = 100.0;
        
        // 根据宠物信息调整价格（如果有petId）
        double petSizeMultiplier = 1.0;
        if (petId != null) {
            // 这里可以根据宠物大小、品种等调整价格
            // 暂时使用固定倍数
            petSizeMultiplier = 1.0;
        }
        
        // 长期寄养折扣
        double discount = 1.0;
        if (days >= 30) {
            discount = 0.8; // 30天以上8折
        } else if (days >= 14) {
            discount = 0.9; // 14天以上9折
        } else if (days >= 7) {
            discount = 0.95; // 7天以上95折
        }
        
        // 计算总价
        double totalCost = basePrice * days * petSizeMultiplier * discount;
        
        // 额外服务费用
        double bathingCost = 50.0 * (days / 7); // 每周洗澡一次
        double groomingCost = 80.0 * (days / 14); // 每两周美容一次
        
        result.put("days", days);
        result.put("basePrice", basePrice);
        result.put("petSizeMultiplier", petSizeMultiplier);
        result.put("discount", discount);
        result.put("baseCost", Math.round(basePrice * days * petSizeMultiplier * 100.0) / 100.0);
        result.put("discountAmount", Math.round((basePrice * days * petSizeMultiplier * (1 - discount)) * 100.0) / 100.0);
        result.put("totalCost", Math.round(totalCost * 100.0) / 100.0);
        result.put("bathingCost", Math.round(bathingCost * 100.0) / 100.0);
        result.put("groomingCost", Math.round(groomingCost * 100.0) / 100.0);
        result.put("grandTotal", Math.round((totalCost + bathingCost + groomingCost) * 100.0) / 100.0);
        
        // 价格明细说明
        List<String> priceDetails = new ArrayList<>();
        priceDetails.add("基础寄养费：¥" + basePrice + "/天 × " + days + "天");
        if (discount < 1.0) {
            priceDetails.add("长期折扣：" + (int)((1 - discount) * 100) + "%优惠");
        }
        priceDetails.add("包含服务：每周洗澡、每两周美容");
        result.put("priceDetails", priceDetails);
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getFosterRooms() {
        List<Map<String, Object>> rooms = new ArrayList<>();
        
        // 模拟寄养房间信息（实际应从数据库查询）
        String[] roomTypes = {"标准间", "豪华间", "VIP套房"};
        int[] basePrices = {100, 150, 200};
        String[][] facilities = {
            {"基础笼舍", "饮水器", "食盆"},
            {"宽敞笼舍", "自动饮水", "智能喂食器", "玩具"},
            {"独立房间", "空调", "监控摄像头", "专属玩具区", "定时播放音乐"}
        };
        int[] totalRooms = {10, 5, 3};
        
        for (int i = 0; i < roomTypes.length; i++) {
            // 模拟已占用房间数
            int occupiedRooms = (int)(Math.random() * totalRooms[i]);
            int availableRooms = totalRooms[i] - occupiedRooms;
            
            Map<String, Object> room = new HashMap<>();
            room.put("id", i + 1);
            room.put("roomType", roomTypes[i]);
            room.put("basePrice", basePrices[i]);
            room.put("priceUnit", "元/天");
            room.put("totalRooms", totalRooms[i]);
            room.put("occupiedRooms", occupiedRooms);
            room.put("availableRooms", availableRooms);
            room.put("occupancyRate", Math.round((double)occupiedRooms / totalRooms[i] * 100.0));
            room.put("facilities", Arrays.asList(facilities[i]));
            room.put("petSizeLimit", i == 0 ? "小型犬/猫" : (i == 1 ? "中型犬" : "大型犬"));
            room.put("status", availableRooms > 0 ? "可预约" : "已满");
            
            rooms.add(room);
        }
        
        return rooms;
    }

    @Override
    public List<Map<String, Object>> getFosterLogs(Long fosterId) {
        List<Map<String, Object>> logs = new ArrayList<>();
        
        if (fosterId == null) {
            return logs;
        }
        
        // 查询寄养预约信息
        ServiceReservation reservation = reservationMapper.selectById(fosterId);
        if (reservation == null) {
            return logs;
        }
        
        // 模拟寄养日志（实际应从专门的日志表查询）
        String[] activities = {
            "宠物入住登记",
            "健康检查完成",
            "喂食 - 早餐",
            "户外活动30分钟",
            "喂食 - 午餐",
            "午休",
            "互动游戏时间",
            "喂食 - 晚餐",
            "晚间巡查",
            "就寝"
        };
        
        String[] statuses = {"正常", "良好", "活跃", "安静"};
        
        LocalDateTime currentTime = LocalDateTime.now();
        
        for (int i = 0; i < 10; i++) {
            Map<String, Object> log = new HashMap<>();
            log.put("id", i + 1);
            log.put("fosterId", fosterId);
            log.put("logTime", currentTime.minusHours(10 - i));
            log.put("activity", activities[i]);
            log.put("status", statuses[i % statuses.length]);
            log.put("description", "宠物" + activities[i] + "，状态" + statuses[i % statuses.length]);
            log.put("recorder", "工作人员" + ((i % 3) + 1));
            log.put("images", new ArrayList<>()); // 可以添加图片URL
            
            logs.add(log);
        }
        
        return logs;
    }

    @Override
    public Map<String, Object> getFosterServiceInfo() {
        Map<String, Object> info = new HashMap<>();
        info.put("pricePerDay", 100);
        info.put("description", "提供专业的宠物寄养服务");
        return info;
    }

    @Override
    public IPage<cn.edu.ncut.cs.springboot.petmanagementsystem.vo.FosterRecordVO> getFosterRecordList(Long userId, Long petId, Integer pageNum, Integer pageSize) {
        Page<cn.edu.ncut.cs.springboot.petmanagementsystem.vo.FosterRecordVO> page = new Page<>(pageNum, pageSize);
        return reservationMapper.selectFosterRecordsWithPetInfo(page, userId, petId);
    }
}
